#pragma once
/***********************************************************************************************
COPYRIGHT 2011 Mafahir Fairoze

This file is part of Neural++.
(Project Website : http://mafahir.wordpress.com/projects/neuralplusplus)

Neural++ is a free software. You can redistribute it and/or modify it under the terms of
the GNU General Public License as published by the Free Software Foundation, either version 3
of the License, or (at your option) any later version.

Neural++ is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License <http://www.gnu.org/licenses/> for more details.

***********************************************************************************************/
#include "../INeighborhoodFunction.h"
#include "../KohonenLayer.h"

namespace NeuralPlusPlus
	{
	namespace Core
		{
		namespace SOM
			{

			namespace NeighborhoodFunctions      
				{
				/// <summary>
				/// Gaussian Neighborhood Function. It is a continuous bell shaped curve centered at winner neuron.
				/// </summary>
				class GaussianFunction : public INeighborhoodFunction
					{
					/* 
					*  Gaussian function = a * Exp( - ((x-b)square) / 2 (c square))
					*
					*  The parameter 'a' is the height of the curve's peak, 'b' is the position of the center of
					*  the peak, and 'c' controls the width of the bell shape.
					*
					*  For a Gaussian Neighborhood function,
					*  a = unity (the neighborhood at the winner)
					*  b = winner position
					*  c = depends on training progress.
					*
					*  Initial value of c is obtained from the user (as learning radius)
					*  Note that, (x-b)square denotes the euclidean distance between winner neuron 'b' and neuron 'x' 
					*
					*                     _._
					*                    /   \
					*                   |     |
					*                  /       \
					*             ___-           -___
					*                      .
					*                Winner Position
					*/

					public: double Sigma;

							/// <summary>
							/// Creates a new Gaussian Neighborhood Function
							/// </summary>
					public: GaussianFunction(double learningRadius);


							/// <summary>
							/// Determines the neighborhood of every neuron in the given Kohonen layer with respect to
							/// winner neuron using Gaussian function
							/// </summary>
					public: void EvaluateNeighborhood(KohonenLayer *layer, int currentIteration, int trainingEpochs);
					};
				}
			}
		}
	}